#include <iostream>
#include <string>
#include <unistd.h>
#include <pthread.h>

// 用宏定全局条件变量和锁，同时访问同一个变量资源时会阻塞
pthread_cond_t gcond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;

void *active(void *args)
{
    std::string name = static_cast<const char *>(args);
    while (true)
    {
        // 对访问显示器进行加锁和解锁，保护临界区
        pthread_mutex_lock(&gmutex);
        //加完锁全部新线程全部阻塞，回去执行main函数的唤醒后再回来执行打印
        //阻塞在gcond 条件变量下等待
        pthread_cond_wait(&gcond, &gmutex);
        std::cout << name << " active !" << std::endl;
        pthread_mutex_unlock(&gmutex);
    }
    return (void *)0;
}

int main()
{
    pthread_t t1, t2, t3, t4;
    pthread_create(&t1, nullptr, active, (void *)"thread-1");
    pthread_create(&t2, nullptr, active, (void *)"thread-2");
    pthread_create(&t3, nullptr, active, (void *)"thread-3");
    pthread_create(&t4, nullptr, active, (void *)"thread-4");

    sleep(5);
    // 唤醒线程
    while (true)
    {
        // pthread_cond_signal(&gcond);唤醒变量下一个线程
        pthread_cond_broadcast(&gcond); // 唤醒变量下全部线程
        sleep(1);
    }

    // 回收线程，避免类似死锁
    pthread_join(t1, nullptr);
    pthread_join(t2, nullptr);
    pthread_join(t3, nullptr);
    pthread_join(t4, nullptr);

    return 0;
}